<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./assets/global.css">
    <title>画垂直线</title>

    <style>
        body {
            text-align: center;
        }

        #line {
            width: 600px;
            height: 600px;
            border: 1px solid #ddd;
            margin: 20px auto;
        }
    </style>


</head>

<body>
    <canvas id="line"></canvas>

    <button id="changeRedirect">切换方向</button>

    <script>

        var arrow = ``

        var arrowImage = new Image()

        arrowImage.src = arrow;

        var c = document.getElementById("line");

        var b = document.getElementById('changeRedirect')

        /** @type {CanvasRenderingContext2D} */
        var ctx = c.getContext("2d");
        c.width = c.clientWidth
        c.height = c.clientHeight

        var isDown = false;
        var startX = 0;
        var startY = 0;
        var endX = 0;
        var endY = 0

        var lasttime = +new Date()
        var timeoutId = null
        var interval = 20
        var redirect = 1;

        function rendering() {
            // 节流 
            // 不怎么会 仅供参考
            if (+new Date() - lasttime < interval) {
                if (!timeoutId)
                    timeoutId = setTimeout(() => {
                        rendering()
                        clearTimeout(timeoutId)
                        timeoutId = null
                    }, 100)
                return;
            }
            lasttime = +new Date()
            clearTimeout(timeoutId)
            // 清理画布
            ctx.clearRect(0, 0, c.clientWidth, c.clientHeight);

            ctx.strokeStyle = "rgb(18,150,219)"
            // 开始路径
            ctx.beginPath();
            // 移动点到开始位置
            ctx.moveTo(startX, startY);
            // 连接到结束点
            ctx.lineTo(endX, endY);
            // 结束
            ctx.stroke();

            // 已知 A⊥B 则 斜率 k1 * k2 = -1
            // 因 k1 = (y2 - y1)/(x2 - x1) 
            // 所以 (y4 - y3)/(x4 - x3) = - (y2 - y1)/(x2 - x1) 
            let x1 = startX
            let y1 = startY
            let x2 = endX
            let y2 = endY

            let k = (y2 - y1) / (x2 - x1)


            let y3 = (y1 + y2) / 2
            let x3 = (x1 + x2) / 2

            // 设 d 为箭头末端距离线的距离
            let d = 20;

            let x4 = 0
            let y4 = 0
            if (x1 == x2) x4 = Math.sign(redirect) * d;
            else if (y1 == y2) y4 = Math.sign(redirect) * d;
            else {
                x4 = Math.sign(redirect) * Math.sqrt(Math.pow(d, 2) / (1 + Math.pow(1 / k, 2)))
                y4 = - 1 / k * x4;
            }

            // 获得角度
            let a = Math.atan2(y4, x4) * 180 / Math.PI
            // 角度偏移值
            a += 90
            // 角度转弧度
            let rd = a * Math.PI / 180
            // 保存画布
            ctx.save()
            // 移动画布
            ctx.translate(x4 + x3, y4 + y3)
            // 旋转画布
            ctx.rotate(rd)
            // 绘制箭头
            ctx.drawImage(arrowImage, -10, -20, 20, 22)
            // 画布还原
            ctx.rotate(-rd)
            ctx.translate(-x4 - x3, -y4 - y3)
            ctx.restore()

            // 辅助线
            // 开始路径
            // ctx.beginPath();
            // 移动点到开始位置
            // ctx.moveTo(x3, y3);
            // 连接到结束点
            // ctx.lineTo(x4 + x3, y4 + y3);
            // 结束
            // ctx.stroke();
        }
        c.addEventListener('mousedown', (ev) => {
            // console.log(ev);
            isDown = true;
            ctx.clearRect(0, 0, c.clientWidth, c.clientHeight);

            startX = ev.offsetX;
            startY = ev.offsetY;
            endX = ev.offsetX;
            endY = ev.offsetY
        })
        c.addEventListener('mousemove', (ev) => {
            // console.log(ev);
            if (!isDown) return;
            endX = ev.offsetX;
            endY = ev.offsetY;
            rendering();
        })
        document.addEventListener('mouseup', (ev) => {
            // console.log(ev);
            isDown = false
        })
        b.addEventListener('click', (ev) => {
            redirect *= -1;
            rendering()
        })
    </script>
</body>

</html>